import * as vscode from "vscode";
import { VsCodeWebviewProtocol } from "./webviewProtocol";
import * as fs from 'fs';
import * as path from 'path';

export class HarmonyPilotGUIWebviewViewProvider implements vscode.WebviewViewProvider {
  private _webview?: vscode.Webview;
  public webviewProtocol: VsCodeWebviewProtocol;

  get webview() {
    return this._webview;
  }

  constructor(
    private readonly _extensionUri: vscode.Uri,
    private readonly _mode: vscode.ExtensionMode,
    private context: vscode.ExtensionContext
  ) {
    this.webviewProtocol = new VsCodeWebviewProtocol(this._webview);
    this.context = context;
  }

  resolveWebviewView(webviewView: vscode.WebviewView) {
    this._webview = webviewView.webview;
    this.webviewProtocol._webview = this._webview;
    webviewView.webview.options = {
      // 在 webview 允许脚本
      enableScripts: true,
      localResourceRoots: [this._extensionUri],
    };

    //  判断是debug还是生产
    //  vscode.ExtensionMode.Production - 扩展从marketplace或VSIX安装并正常运行时
    //  vscode.ExtensionMode.Development - 扩展在开发模式下运行，通常是通过F5或VSCode调试时
    const inDevelopmentMode = this._mode === vscode.ExtensionMode.Development;
    if (!inDevelopmentMode) {
      webviewView.webview.html = this.getProductionHtml(webviewView.webview);
    } else {
      webviewView.webview.html = this.getDebugHtml(webviewView.webview);
    }
    webviewView.webview.onDidReceiveMessage(
      (message) => {
        const isDark =
          vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.Dark;
        switch (message.messageType) {
          case "webviewLoaded":
            webviewView.webview.postMessage({
              messageType: "themeChange",
              data: {
                isDark,
              },
            });
            break;
          case "insertCode":
            this.insertCode(message.data);
            break;
          case "copyText":
            this.copyText(message.data);
            break;
          default:
            vscode.window.showInformationMessage(message.data);
            break;
        }
      },
      undefined,
      this.context.subscriptions
    );
    // 监听主题变化
    vscode.window.onDidChangeActiveColorTheme((theme) => {
      const isDark = theme.kind === vscode.ColorThemeKind.Dark;
      webviewView.webview.postMessage({
        messageType: "themeChange",
        data: {
          isDark,
        },
      });
    });
  }

  getDebugHtml(webview: vscode.Webview) {
    const staticPath = String(
      webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri))
    );
    return `
        <!DOCTYPE html>
        <html>
            <head>
                <title>HarmonyPilot</title>
                <link rel="stylesheet" href="http://localhost:5174/node_modules/@devui-design/icons/icomoon/devui-icon.css">
                <link rel="stylesheet" href="http://localhost:5174/src/style.css">
            </head>
            <body>
                <div id="app"></div>
                <script type="module" src="http://localhost:5174/src/main.ts"></script>
                <script>
                window.staticPath = '${staticPath}';
                window.vscode = acquireVsCodeApi && acquireVsCodeApi();
                </script>
            </body>
        </html>`;
  }

  getProductionHtml(webview: vscode.Webview) {
    const staticPath = String(
      webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri))
    );
    const fontUri = String(
      webview.asWebviewUri(
        vscode.Uri.file(
          path.join(
            this._extensionUri.fsPath,
            "dist/assets",
            "devui-icomoon.woff"
          )
        )
      )
    );
    const code = fs.readFileSync(
      path.resolve(this._extensionUri.fsPath, "dist/index.html"),
      "utf-8"
    );
    const files = fs.readdirSync(
      path.resolve(this._extensionUri.fsPath, "dist/assets")
    );
    let jsFile = "";
    let cssFile = "";
    for (const file of files) {
      if (file.endsWith("js")) {
        jsFile = file;
      } else if (file.endsWith("css")) {
        cssFile = file;
      } else {
      }
    }
    const curPath = vscode.Uri.joinPath(
      this._extensionUri,
      "dist/assets",
      jsFile
    );
    const curCssPath = vscode.Uri.joinPath(
      this._extensionUri,
      "dist/assets",
      cssFile
    );
    const jsSrc = this.webview?.asWebviewUri(curPath);
    const cssSrc = this.webview?.asWebviewUri(curCssPath);
    let result = code.replace(/<script.*?src="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/src="(.+?)"/, (src: string) => {
        return `src="${jsSrc}"`;
      });
    });
    result = result.replace(/<link.*?href="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/href="(.+?)"/, (src: string) => {
        return `href="${cssSrc}"`;
      });
    });
    result = result.replaceAll("${staticPath}", staticPath);
    result = result.replace("${fontUri}", fontUri);
    return result;
  }

  insertCode(data: any) {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
      vscode.window.showErrorMessage("无活动编辑器！");
      return;
    }
    const codeSnippet = (data.code as string)
      .replace(/\\/g, "\\\\")
      .replace(/\$/g, "\\$");
    // 执行插入操作
    vscode.window.activeTextEditor?.insertSnippet(new vscode.SnippetString(codeSnippet));
  }

  copyText(data: any) {
    vscode.env.clipboard.writeText(data.code).then(() => {
      vscode.window.showInformationMessage("复制成功！");
    });
  }
}
